home *** CD-ROM | disk | FTP | other *** search
- /* $Id: nurbssrf.c,v 1.2 1996/09/27 23:13:02 brianp Exp $ */
-
- /*
- * Mesa 3-D graphics library
- * Version: 2.0
- * Copyright (C) 1995-1996 Brian Paul
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
- /*
- * $Log: nurbssrf.c,v $
- * Revision 1.2 1996/09/27 23:13:02 brianp
- * added return 0 to get_surface_dim() to silence warning
- *
- * Revision 1.1 1996/09/27 01:19:39 brianp
- * Initial revision
- *
- */
-
-
- /*
- * NURBS implementation written by Bogdan Sikorski (bogdan@cira.it)
- * See README2 for more info.
- */
-
-
- #include <math.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h> /* prototype of memcpy() */
- #include "nurbs.h"
-
-
- static int
- get_surface_dim(GLenum type)
- {
- switch(type)
- {
- case GL_MAP2_VERTEX_3: return 3;
- case GL_MAP2_VERTEX_4: return 4;
- case GL_MAP2_INDEX: return 1;
- case GL_MAP2_COLOR_4: return 4;
- case GL_MAP2_NORMAL: return 3;
- case GL_MAP2_TEXTURE_COORD_1: return 1;
- case GL_MAP2_TEXTURE_COORD_2: return 2;
- case GL_MAP2_TEXTURE_COORD_3: return 3;
- case GL_MAP2_TEXTURE_COORD_4: return 4;
- default: abort(); /* TODO: is this OK? */
- }
- return 0; /*never get here*/
- }
-
- static GLenum
- test_nurbs_surface(GLUnurbsObj *nobj, surface_attribs *attrib)
- {
- GLenum err;
- GLint tmp_int;
-
- if(attrib->sorder < 0 || attrib->torder < 0)
- {
- call_user_error(nobj,GLU_INVALID_VALUE);
- return GLU_ERROR;
- }
- glGetIntegerv(GL_MAX_EVAL_ORDER,&tmp_int);
- if(attrib->sorder > tmp_int || attrib->sorder < 2)
- {
- call_user_error(nobj,GLU_NURBS_ERROR1);
- return GLU_ERROR;
- }
- if(attrib->torder > tmp_int || attrib->torder < 2)
- {
- call_user_error(nobj,GLU_NURBS_ERROR1);
- return GLU_ERROR;
- }
- if(attrib->sknot_count < attrib->sorder +2)
- {
- call_user_error(nobj,GLU_NURBS_ERROR2);
- return GLU_ERROR;
- }
- if(attrib->tknot_count < attrib->torder +2)
- {
- call_user_error(nobj,GLU_NURBS_ERROR2);
- return GLU_ERROR;
- }
- if(attrib->s_stride < 0 || attrib->t_stride < 0)
- {
- call_user_error(nobj,GLU_NURBS_ERROR34);
- return GLU_ERROR;
- }
- if(attrib->sknot==NULL || attrib->tknot==NULL || attrib->ctrlarray==NULL)
- {
- call_user_error(nobj,GLU_NURBS_ERROR36);
- return GLU_ERROR;
- }
- if((err=test_knot(attrib->tknot_count,attrib->tknot,attrib->torder))
- !=GLU_NO_ERROR)
- {
- call_user_error(nobj,err);
- return GLU_ERROR;
- }
- if((err=test_knot(attrib->sknot_count,attrib->sknot,attrib->sorder))
- !=GLU_NO_ERROR)
- {
- call_user_error(nobj,err);
- return GLU_ERROR;
- }
- return GLU_NO_ERROR;
- }
-
- static GLenum
- test_nurbs_surfaces(GLUnurbsObj *nobj)
- {
- /* test the geometric data */
- if(test_nurbs_surface(nobj,&(nobj->surface.geom))!=GLU_NO_ERROR)
- return GLU_ERROR;
- /* now test the attributive data */
- /* color */
- if(nobj->surface.color.type!=GLU_INVALID_ENUM)
- if(test_nurbs_surface(nobj,&(nobj->surface.color))!=GLU_NO_ERROR)
- return GLU_ERROR;
- /* normal */
- if(nobj->surface.normal.type!=GLU_INVALID_ENUM)
- if(test_nurbs_surface(nobj,&(nobj->surface.normal))!=GLU_NO_ERROR)
- return GLU_ERROR;
- /* texture */
- if(nobj->surface.texture.type!=GLU_INVALID_ENUM)
- if(test_nurbs_surface(nobj,&(nobj->surface.texture))!=GLU_NO_ERROR)
- return GLU_ERROR;
- return GLU_NO_ERROR;
- }
-
- static GLenum
- convert_surf(knot_str_type *s_knot, knot_str_type *t_knot,
- surface_attribs *attrib, GLfloat **new_ctrl,
- GLint *s_n_ctrl, GLint *t_n_ctrl)
- {
- GLfloat **tmp_ctrl;
- GLfloat *ctrl_offset;
- GLint tmp_n_control;
- GLint i,j,t_cnt,s_cnt;
- GLint tmp_stride;
- GLint dim;
- GLenum err;
-
- /* valid range is empty? */
- if((s_knot->unified_knot !=NULL && s_knot->unified_nknots==0) ||
- (t_knot->unified_knot !=NULL && t_knot->unified_nknots==0))
- {
- if(s_knot->unified_knot)
- {
- free(s_knot->unified_knot);
- s_knot->unified_knot=NULL;
- }
- if(t_knot->unified_knot)
- {
- free(t_knot->unified_knot);
- t_knot->unified_knot=NULL;
- }
- *s_n_ctrl=0;
- *t_n_ctrl=0;
- return GLU_NO_ERROR;
- }
- t_cnt=attrib->tknot_count-attrib->torder;
- s_cnt=attrib->sknot_count-attrib->sorder;
- if((tmp_ctrl=(GLfloat **)malloc(sizeof(GLfloat *)*t_cnt))==NULL)
- return GLU_OUT_OF_MEMORY;
- if((err=explode_knot(s_knot))!=GLU_NO_ERROR)
- {
- free(tmp_ctrl);
- if(s_knot->unified_knot)
- {
- free(s_knot->unified_knot);
- s_knot->unified_knot=NULL;
- }
- return err;
- }
- if(s_knot->unified_knot)
- {
- free(s_knot->unified_knot);
- s_knot->unified_knot=NULL;
- }
- if((err=calc_alphas(s_knot))!=GLU_NO_ERROR)
- {
- free(tmp_ctrl);
- free(s_knot->new_knot);
- return err;
- }
- free(s_knot->new_knot);
- ctrl_offset=attrib->ctrlarray;
- dim=attrib->dim;
- for(i=0;i<t_cnt;i++)
- {
- if((err=calc_new_ctrl_pts(ctrl_offset,attrib->s_stride,s_knot,
- dim,&(tmp_ctrl[i]),&tmp_n_control))!=GLU_NO_ERROR)
- {
- for(--i;i<=0;i--)
- free(tmp_ctrl[i]);
- free(tmp_ctrl);
- free(s_knot->alpha);
- return err;
- }
- ctrl_offset+=attrib->t_stride;
- }
- free(s_knot->alpha);
- tmp_stride=dim*tmp_n_control;
- if((*new_ctrl=(GLfloat *)malloc(sizeof(GLfloat)*tmp_stride*t_cnt))
- ==NULL)
- {
- for(i=0;i<t_cnt;i++)
- free(tmp_ctrl[i]);
- free(tmp_ctrl);
- return GLU_OUT_OF_MEMORY;
- }
- for(i=0;i<tmp_n_control;i++)
- for(j=0;j<t_cnt;j++)
- MEMCPY(*new_ctrl+j*dim+i*dim*t_cnt,tmp_ctrl[j]+dim*i,
- sizeof(GLfloat)*dim);
- for(i=0;i<t_cnt;i++)
- free(tmp_ctrl[i]);
- free(tmp_ctrl);
- *s_n_ctrl=tmp_n_control;
-
- if((tmp_ctrl=(GLfloat **)malloc(sizeof(GLfloat *)*(*s_n_ctrl)))==NULL)
- {
- return GLU_OUT_OF_MEMORY;
- }
- if((err=explode_knot(t_knot))!=GLU_NO_ERROR)
- {
- free(tmp_ctrl);
- if(t_knot->unified_knot)
- {
- free(t_knot->unified_knot);
- t_knot->unified_knot=NULL;
- }
- return err;
- }
- if(t_knot->unified_knot)
- {
- free(t_knot->unified_knot);
- t_knot->unified_knot=NULL;
- }
- if((err=calc_alphas(t_knot))!=GLU_NO_ERROR)
- {
- free(tmp_ctrl);
- free(t_knot->new_knot);
- return err;
- }
- free(t_knot->new_knot);
- ctrl_offset=*new_ctrl;
- for(i=0;i<(*s_n_ctrl);i++)
- {
- if((err=calc_new_ctrl_pts(ctrl_offset,dim,t_knot,
- dim,&(tmp_ctrl[i]),&tmp_n_control))!=GLU_NO_ERROR)
- {
- for(--i;i<=0;i--)
- free(tmp_ctrl[i]);
- free(tmp_ctrl);
- free(t_knot->alpha);
- return err;
- }
- ctrl_offset+=dim*t_cnt;
- }
- free(t_knot->alpha);
- free(*new_ctrl);
- tmp_stride=dim*tmp_n_control;
- if((*new_ctrl=(GLfloat *)malloc(sizeof(GLfloat)*tmp_stride*(*s_n_ctrl)))
- ==NULL)
- {
- for(i=0;i<(*s_n_ctrl);i++)
- free(tmp_ctrl[i]);
- free(tmp_ctrl);
- return GLU_OUT_OF_MEMORY;
- }
- for(i=0;i<(*s_n_ctrl);i++)
- {
- MEMCPY(*new_ctrl+i*tmp_stride,tmp_ctrl[i],sizeof(GLfloat)*tmp_stride);
- free(tmp_ctrl[i]);
- }
- free(tmp_ctrl);
- *t_n_ctrl=tmp_n_control;
- return GLU_NO_ERROR;
- }
-
- /* prepare the knot information structures */
- static GLenum
- fill_knot_structures(GLUnurbsObj *nobj,
- knot_str_type *geom_s_knot, knot_str_type *geom_t_knot,
- knot_str_type *color_s_knot, knot_str_type *color_t_knot,
- knot_str_type *normal_s_knot, knot_str_type *normal_t_knot,
- knot_str_type *texture_s_knot, knot_str_type *texture_t_knot)
- {
- GLint order;
- GLfloat *knot;
- GLint nknots;
- GLint t_min,t_max;
-
- geom_s_knot->unified_knot=NULL;
- knot=geom_s_knot->knot=nobj->surface.geom.sknot;
- nknots=geom_s_knot->nknots=nobj->surface.geom.sknot_count;
- order=geom_s_knot->order=nobj->surface.geom.sorder;
- geom_s_knot->delta_nknots=0;
- t_min=geom_s_knot->t_min=order-1;
- t_max=geom_s_knot->t_max=nknots-order;
- if(fabs(knot[t_min]-knot[t_max])<EPSILON)
- {
- call_user_error(nobj,GLU_NURBS_ERROR3);
- return GLU_ERROR;
- }
- if(fabs(knot[0]-knot[t_min])<EPSILON)
- {
- /* knot open at beggining */
- geom_s_knot->open_at_begin=GL_TRUE;
- }
- else
- geom_s_knot->open_at_begin=GL_FALSE;
- if(fabs(knot[t_max]-knot[nknots-1])<EPSILON)
- {
- /* knot open at end */
- geom_s_knot->open_at_end=GL_TRUE;
- }
- else
- geom_s_knot->open_at_end=GL_FALSE;
- geom_t_knot->unified_knot=NULL;
- knot=geom_t_knot->knot=nobj->surface.geom.tknot;
- nknots=geom_t_knot->nknots=nobj->surface.geom.tknot_count;
- order=geom_t_knot->order=nobj->surface.geom.torder;
- geom_t_knot->delta_nknots=0;
- t_min=geom_t_knot->t_min=order-1;
- t_max=geom_t_knot->t_max=nknots-order;
- if(fabs(knot[t_min]-knot[t_max])<EPSILON)
- {
- call_user_error(nobj,GLU_NURBS_ERROR3);
- return GLU_ERROR;
- }
- if(fabs(knot[0]-knot[t_min])<EPSILON)
- {
- /* knot open at beggining */
- geom_t_knot->open_at_begin=GL_TRUE;
- }
- else
- geom_t_knot->open_at_begin=GL_FALSE;
- if(fabs(knot[t_max]-knot[nknots-1])<EPSILON)
- {
- /* knot open at end */
- geom_t_knot->open_at_end=GL_TRUE;
- }
- else
- geom_t_knot->open_at_end=GL_FALSE;
-
- if(nobj->surface.color.type!=GLU_INVALID_ENUM)
- {
- color_s_knot->unified_knot=(GLfloat *)1;
- knot=color_s_knot->knot=nobj->surface.color.sknot;
- nknots=color_s_knot->nknots=nobj->surface.color.sknot_count;
- order=color_s_knot->order=nobj->surface.color.sorder;
- color_s_knot->delta_nknots=0;
- t_min=color_s_knot->t_min=order-1;
- t_max=color_s_knot->t_max=nknots-order;
- if(fabs(knot[t_min]-knot[t_max])<EPSILON)
- {
- call_user_error(nobj,GLU_NURBS_ERROR3);
- return GLU_ERROR;
- }
- if(fabs(knot[0]-knot[t_min])<EPSILON)
- {
- /* knot open at beggining */
- color_s_knot->open_at_begin=GL_TRUE;
- }
- else
- color_s_knot->open_at_begin=GL_FALSE;
- if(fabs(knot[t_max]-knot[nknots-1])<EPSILON)
- {
- /* knot open at end */
- color_s_knot->open_at_end=GL_TRUE;
- }
- else
- color_s_knot->open_at_end=GL_FALSE;
- color_t_knot->unified_knot=(GLfloat *)1;
- knot=color_t_knot->knot=nobj->surface.color.tknot;
- nknots=color_t_knot->nknots=nobj->surface.color.tknot_count;
- order=color_t_knot->order=nobj->surface.color.torder;
- color_t_knot->delta_nknots=0;
- t_min=color_t_knot->t_min=order-1;
- t_max=color_t_knot->t_max=nknots-order;
- if(fabs(knot[t_min]-knot[t_max])<EPSILON)
- {
- call_user_error(nobj,GLU_NURBS_ERROR3);
- return GLU_ERROR;
- }
- if(fabs(knot[0]-knot[t_min])<EPSILON)
- {
- /* knot open at beggining */
- color_t_knot->open_at_begin=GL_TRUE;
- }
- else
- color_t_knot->open_at_begin=GL_FALSE;
- if(fabs(knot[t_max]-knot[nknots-1])<EPSILON)
- {
- /* knot open at end */
- color_t_knot->open_at_end=GL_TRUE;
- }
- else
- color_t_knot->open_at_end=GL_FALSE;
- }
- else
- {
- color_s_knot->unified_knot=NULL;
- color_t_knot->unified_knot=NULL;
- }
-
- if(nobj->surface.normal.type!=GLU_INVALID_ENUM)
- {
- normal_s_knot->unified_knot=(GLfloat *)1;
- knot=normal_s_knot->knot=nobj->surface.normal.sknot;
- nknots=normal_s_knot->nknots=nobj->surface.normal.sknot_count;
- order=normal_s_knot->order=nobj->surface.normal.sorder;
- normal_s_knot->delta_nknots=0;
- t_min=normal_s_knot->t_min=order-1;
- t_max=normal_s_knot->t_max=nknots-order;
- if(fabs(knot[t_min]-knot[t_max])<EPSILON)
- {
- call_user_error(nobj,GLU_NURBS_ERROR3);
- return GLU_ERROR;
- }
- if(fabs(knot[0]-knot[t_min])<EPSILON)
- {
- /* knot open at beggining */
- normal_s_knot->open_at_begin=GL_TRUE;
- }
- else
- normal_s_knot->open_at_begin=GL_FALSE;
- if(fabs(knot[t_max]-knot[nknots-1])<EPSILON)
- {
- /* knot open at end */
- normal_s_knot->open_at_end=GL_TRUE;
- }
- else
- normal_s_knot->open_at_end=GL_FALSE;
- normal_t_knot->unified_knot=(GLfloat *)1;
- knot=normal_t_knot->knot=nobj->surface.normal.tknot;
- nknots=normal_t_knot->nknots=nobj->surface.normal.tknot_count;
- order=normal_t_knot->order=nobj->surface.normal.torder;
- normal_t_knot->delta_nknots=0;
- t_min=normal_t_knot->t_min=order-1;
- t_max=normal_t_knot->t_max=nknots-order;
- if(fabs(knot[t_min]-knot[t_max])<EPSILON)
- {
- call_user_error(nobj,GLU_NURBS_ERROR3);
- return GLU_ERROR;
- }
- if(fabs(knot[0]-knot[t_min])<EPSILON)
- {
- /* knot open at beggining */
- normal_t_knot->open_at_begin=GL_TRUE;
- }
- else
- normal_t_knot->open_at_begin=GL_FALSE;
- if(fabs(knot[t_max]-knot[nknots-1])<EPSILON)
- {
- /* knot open at end */
- normal_t_knot->open_at_end=GL_TRUE;
- }
- else
- normal_t_knot->open_at_end=GL_FALSE;
- }
- else
- {
- normal_s_knot->unified_knot=NULL;
- normal_t_knot->unified_knot=NULL;
- }
-
- if(nobj->surface.texture.type!=GLU_INVALID_ENUM)
- {
- texture_s_knot->unified_knot=(GLfloat *)1;
- knot=texture_s_knot->knot=nobj->surface.texture.sknot;
- nknots=texture_s_knot->nknots=nobj->surface.texture.sknot_count;
- order=texture_s_knot->order=nobj->surface.texture.sorder;
- texture_s_knot->delta_nknots=0;
- t_min=texture_s_knot->t_min=order-1;
- t_max=texture_s_knot->t_max=nknots-order;
- if(fabs(knot[t_min]-knot[t_max])<EPSILON)
- {
- call_user_error(nobj,GLU_NURBS_ERROR3);
- return GLU_ERROR;
- }
- if(fabs(knot[0]-knot[t_min])<EPSILON)
- {
- /* knot open at beggining */
- texture_s_knot->open_at_begin=GL_TRUE;
- }
- else
- texture_s_knot->open_at_begin=GL_FALSE;
- if(fabs(knot[t_max]-knot[nknots-1])<EPSILON)
- {
- /* knot open at end */
- texture_s_knot->open_at_end=GL_TRUE;
- }
- else
- texture_s_knot->open_at_end=GL_FALSE;
- texture_t_knot->unified_knot=(GLfloat *)1;
- knot=texture_t_knot->knot=nobj->surface.texture.tknot;
- nknots=texture_t_knot->nknots=nobj->surface.texture.tknot_count;
- order=texture_t_knot->order=nobj->surface.texture.torder;
- texture_t_knot->delta_nknots=0;
- t_min=texture_t_knot->t_min=order-1;
- t_max=texture_t_knot->t_max=nknots-order;
- if(fabs(knot[t_min]-knot[t_max])<EPSILON)
- {
- call_user_error(nobj,GLU_NURBS_ERROR3);
- return GLU_ERROR;
- }
- if(fabs(knot[0]-knot[t_min])<EPSILON)
- {
- /* knot open at beggining */
- texture_t_knot->open_at_begin=GL_TRUE;
- }
- else
- texture_t_knot->open_at_begin=GL_FALSE;
- if(fabs(knot[t_max]-knot[nknots-1])<EPSILON)
- {
- /* knot open at end */
- texture_t_knot->open_at_end=GL_TRUE;
- }
- else
- texture_t_knot->open_at_end=GL_FALSE;
- }
- else
- {
- texture_s_knot->unified_knot=NULL;
- texture_t_knot->unified_knot=NULL;
- }
- return GLU_NO_ERROR;
- }
-
- void
- free_new_ctrl(new_ctrl_type *p)
- {
- if(p->geom_ctrl)
- free(p->geom_ctrl);
- if(p->geom_offsets)
- free(p->geom_offsets);
- if(p->color_ctrl)
- {
- free(p->color_ctrl);
- if(p->color_offsets)
- free(p->color_offsets);
- }
- if(p->normal_ctrl)
- {
- free(p->normal_ctrl);
- if(p->normal_offsets)
- free(p->normal_offsets);
- }
- if(p->texture_ctrl)
- {
- free(p->texture_ctrl);
- if(p->texture_offsets)
- free(p->texture_offsets);
- }
- }
-
- /* convert surfaces - geometry and possible attribute ones into equivalent */
- /* sequence of adjacent Bezier patches */
- static GLenum
- convert_surfs(GLUnurbsObj *nobj, new_ctrl_type *new_ctrl)
- {
- knot_str_type geom_s_knot,color_s_knot,normal_s_knot,texture_s_knot;
- knot_str_type geom_t_knot,color_t_knot,normal_t_knot,texture_t_knot;
- GLenum err;
-
- if((err=fill_knot_structures(nobj,&geom_s_knot,&geom_t_knot,
- &color_s_knot,&color_t_knot,&normal_s_knot,&normal_t_knot,
- &texture_s_knot,&texture_t_knot)) !=GLU_NO_ERROR)
- {
- return err;
- }
- /* unify knots - all knots should have the same working range */
- if((err=select_knot_working_range(nobj,&geom_s_knot,&color_s_knot,
- &normal_s_knot,&texture_s_knot)) !=GLU_NO_ERROR)
- {
- call_user_error(nobj,err);
- return err;
- }
- if((err=select_knot_working_range(nobj,&geom_t_knot,&color_t_knot,
- &normal_t_knot,&texture_t_knot)) !=GLU_NO_ERROR)
- {
- free_unified_knots(&geom_s_knot,&color_s_knot,&normal_s_knot,
- &texture_s_knot);
- call_user_error(nobj,err);
- return err;
- }
-
- /* convert the geometry surface */
- nobj->surface.geom.dim=get_surface_dim(nobj->surface.geom.type);
- if((err=convert_surf(&geom_s_knot,&geom_t_knot,&(nobj->surface.geom),
- &(new_ctrl->geom_ctrl),&(new_ctrl->geom_s_pt_cnt),
- &(new_ctrl->geom_t_pt_cnt)))!=GLU_NO_ERROR)
- {
- free_unified_knots(&geom_s_knot,&color_s_knot,&normal_s_knot,
- &texture_s_knot);
- free_unified_knots(&geom_t_knot,&color_t_knot,&normal_t_knot,
- &texture_t_knot);
- call_user_error(nobj,err);
- return err;
- }
- /* if additional attributive surfaces are given convert them as well */
- if(color_s_knot.unified_knot)
- {
- nobj->surface.color.dim=get_surface_dim(nobj->surface.color.type);
- if((err=convert_surf(&color_s_knot,&color_t_knot,&(nobj->surface.color),
- &(new_ctrl->color_ctrl),&(new_ctrl->color_s_pt_cnt),
- &(new_ctrl->color_t_pt_cnt)))!=GLU_NO_ERROR)
- {
- free_unified_knots(&color_s_knot,&color_s_knot,&normal_s_knot,
- &texture_s_knot);
- free_unified_knots(&color_t_knot,&color_t_knot,&normal_t_knot,
- &texture_t_knot);
- free_new_ctrl(new_ctrl);
- call_user_error(nobj,err);
- return err;
- }
- }
- if(normal_s_knot.unified_knot)
- {
- nobj->surface.normal.dim=get_surface_dim(nobj->surface.normal.type);
- if((err=convert_surf(&normal_s_knot,&normal_t_knot,
- &(nobj->surface.normal),
- &(new_ctrl->normal_ctrl),&(new_ctrl->normal_s_pt_cnt),
- &(new_ctrl->normal_t_pt_cnt)))!=GLU_NO_ERROR)
- {
- free_unified_knots(&normal_s_knot,&normal_s_knot,&normal_s_knot,
- &texture_s_knot);
- free_unified_knots(&normal_t_knot,&normal_t_knot,&normal_t_knot,
- &texture_t_knot);
- free_new_ctrl(new_ctrl);
- call_user_error(nobj,err);
- return err;
- }
- }
- if(texture_s_knot.unified_knot)
- {
- nobj->surface.texture.dim=get_surface_dim(nobj->surface.texture.type);
- if((err=convert_surf(&texture_s_knot,&texture_t_knot,
- &(nobj->surface.texture),
- &(new_ctrl->texture_ctrl),&(new_ctrl->texture_s_pt_cnt),
- &(new_ctrl->texture_t_pt_cnt)))!=GLU_NO_ERROR)
- {
- free_unified_knots(&texture_s_knot,&texture_s_knot,&texture_s_knot,
- &texture_s_knot);
- free_unified_knots(&texture_t_knot,&texture_t_knot,&texture_t_knot,
- &texture_t_knot);
- free_new_ctrl(new_ctrl);
- call_user_error(nobj,err);
- return err;
- }
- }
- return GLU_NO_ERROR;
- }
-
- /* tesselate the "boundary" Bezier edge strips */
- void
- tesselate_strip_t_line(GLint top_start,GLint top_end,GLint top_z,
- GLint bottom_start,GLint bottom_end,GLint bottom_z,GLint bottom_domain)
- {
- GLint top_cnt,bottom_cnt,tri_cnt,k;
- GLint direction;
-
- top_cnt=top_end-top_start;
- direction= (top_cnt>=0 ? 1: -1);
- bottom_cnt=bottom_end-bottom_start;
- glBegin(GL_LINES);
- while(top_cnt)
- {
- if(bottom_cnt)
- tri_cnt=top_cnt/bottom_cnt;
- else
- tri_cnt=abs(top_cnt);
- for(k=0;k<=tri_cnt;k++ , top_start+=direction)
- {
- glEvalCoord2f((GLfloat)bottom_z/bottom_domain,
- (GLfloat)bottom_start/bottom_domain);
- glEvalPoint2(top_z,top_start);
- }
- if(bottom_cnt)
- {
- glEvalCoord2f((GLfloat)bottom_z/bottom_domain,
- (GLfloat)bottom_start/bottom_domain);
- bottom_start+=direction;
- top_start-=direction;
- glEvalCoord2f((GLfloat)bottom_z/bottom_domain,
- (GLfloat)bottom_start/bottom_domain);
- glEvalCoord2f((GLfloat)bottom_z/bottom_domain,
- (GLfloat)bottom_start/bottom_domain);
- glEvalPoint2(top_z,top_start);
- }
- top_cnt-=direction*tri_cnt;
- bottom_cnt-=direction;
- }
- glEnd();
- }
-
- void
- tesselate_strip_t_fill(GLint top_start,GLint top_end,GLint top_z,
- GLint bottom_start,GLint bottom_end,GLint bottom_z,GLint bottom_domain)
- {
- GLint top_cnt,bottom_cnt,tri_cnt,k;
- GLint direction;
-
- top_cnt=top_end-top_start;
- direction= (top_cnt>=0 ? 1: -1);
- bottom_cnt=bottom_end-bottom_start;
- while(top_cnt)
- {
- if(bottom_cnt)
- tri_cnt=top_cnt/bottom_cnt;
- else
- tri_cnt=abs(top_cnt);
- glBegin(GL_TRIANGLE_FAN);
- glEvalCoord2f((GLfloat)bottom_z/bottom_domain,
- (GLfloat)bottom_start/bottom_domain);
- for(k=0;k<=tri_cnt;k++ , top_start+=direction)
- glEvalPoint2(top_z,top_start);
- if(bottom_cnt)
- {
- bottom_start+=direction;
- top_start-=direction;
- glEvalCoord2f((GLfloat)bottom_z/bottom_domain,
- (GLfloat)bottom_start/bottom_domain);
- }
- glEnd();
- top_cnt-=direction*tri_cnt;
- bottom_cnt-=direction;
- }
- }
-
- void
- tesselate_strip_t(GLenum display_mode, GLint top_start, GLint top_end,
- GLint top_z, GLint bottom_start, GLint bottom_end, GLint bottom_z,
- GLint bottom_domain)
- {
- if(display_mode==GL_FILL)
- tesselate_strip_t_fill(top_start,top_end,top_z,bottom_start,
- bottom_end,bottom_z,bottom_domain);
- else
- tesselate_strip_t_line(top_start,top_end,top_z,bottom_start,
- bottom_end,bottom_z,bottom_domain);
- }
-
-
- void
- tesselate_strip_s_fill(GLint top_start, GLint top_end, GLint top_z,
- GLint bottom_start, GLint bottom_end, GLint bottom_z, GLfloat bottom_domain)
- {
- GLint top_cnt,bottom_cnt,tri_cnt,k;
- GLint direction;
-
- top_cnt=top_end-top_start;
- direction= (top_cnt>=0 ? 1: -1);
- bottom_cnt=bottom_end-bottom_start;
- while(top_cnt)
- {
- if(bottom_cnt)
- tri_cnt=top_cnt/bottom_cnt;
- else
- tri_cnt=abs(top_cnt);
- glBegin(GL_TRIANGLE_FAN);
- glEvalCoord2f((GLfloat)bottom_start/bottom_domain,
- (GLfloat)bottom_z/bottom_domain);
- for(k=0;k<=tri_cnt;k++ , top_start+=direction)
- glEvalPoint2(top_start,top_z);
- if(bottom_cnt)
- {
- bottom_start+=direction;
- top_start-=direction;
- glEvalCoord2f((GLfloat)bottom_start/bottom_domain,
- (GLfloat)bottom_z/bottom_domain);
- }
- glEnd();
- top_cnt-=direction*tri_cnt;
- bottom_cnt-=direction;
- }
- }
-
- void
- tesselate_strip_s_line(GLint top_start, GLint top_end, GLint top_z,
- GLint bottom_start, GLint bottom_end, GLint bottom_z, GLfloat bottom_domain)
- {
- GLint top_cnt,bottom_cnt,tri_cnt,k;
- GLint direction;
-
- top_cnt=top_end-top_start;
- direction= (top_cnt>=0 ? 1: -1);
- bottom_cnt=bottom_end-bottom_start;
- glBegin(GL_LINES);
- while(top_cnt)
- {
- if(bottom_cnt)
- tri_cnt=top_cnt/bottom_cnt;
- else
- tri_cnt=abs(top_cnt);
- for(k=0;k<=tri_cnt;k++ , top_start+=direction)
- {
- glEvalCoord2f((GLfloat)bottom_start/bottom_domain,
- (GLfloat)bottom_z/bottom_domain);
- glEvalPoint2(top_start,top_z);
- }
- if(bottom_cnt)
- {
- glEvalCoord2f((GLfloat)bottom_start/bottom_domain,
- (GLfloat)bottom_z/bottom_domain);
- bottom_start+=direction;
- top_start-=direction;
- glEvalCoord2f((GLfloat)bottom_start/bottom_domain,
- (GLfloat)bottom_z/bottom_domain);
- glEvalPoint2(top_start,top_z);
- glEvalCoord2f((GLfloat)bottom_start/bottom_domain,
- (GLfloat)bottom_z/bottom_domain);
- }
- top_cnt-=direction*tri_cnt;
- bottom_cnt-=direction;
- }
- glEnd();
- }
-
- void
- tesselate_strip_s(GLenum display_mode, GLint top_start, GLint top_end,
- GLint top_z, GLint bottom_start, GLint bottom_end, GLint bottom_z,
- GLfloat bottom_domain)
- {
- if(display_mode==GL_FILL)
- tesselate_strip_s_fill(top_start,top_end,top_z,bottom_start,
- bottom_end,bottom_z,bottom_domain);
- else
- tesselate_strip_s_line(top_start,top_end,top_z,bottom_start,
- bottom_end,bottom_z,bottom_domain);
- }
-
- void
- tesselate_bottom_left_corner(GLenum display_mode, GLfloat s_1, GLfloat t_1)
- {
- if(display_mode==GL_FILL)
- {
- glBegin(GL_TRIANGLE_FAN);
- glEvalPoint2(1,1);
- glEvalCoord2f(s_1,0.0);
- glEvalCoord2f(0.0,0.0);
- glEvalCoord2f(0.0,t_1);
- }
- else
- {
- glBegin(GL_LINES);
- glEvalCoord2f(0.0,0.0);
- glEvalCoord2f(0.0,t_1);
- glEvalCoord2f(0.0,0.0);
- glEvalPoint2(1,1);
- glEvalCoord2f(0.0,0.0);
- glEvalCoord2f(s_1,0.0);
- }
- glEnd();
- }
-
- void
- tesselate_bottom_right_corner(GLenum display_mode, GLint v_top,GLint v_bottom,
- GLfloat s_1, GLfloat t_1)
- {
- if(display_mode==GL_FILL)
- {
- glBegin(GL_TRIANGLE_FAN);
- glEvalPoint2(1,v_top);
- glEvalCoord2f(0.0,v_bottom*t_1);
- glEvalCoord2f(0.0,(v_bottom+1)*t_1);
- glEvalCoord2f(s_1,(v_bottom+1)*t_1);
- }
- else
- {
- glBegin(GL_LINES);
- glEvalCoord2f(0.0,(v_bottom+1)*t_1);
- glEvalPoint2(1,v_top);
- glEvalCoord2f(0.0,(v_bottom+1)*t_1);
- glEvalCoord2f(0.0,v_bottom*t_1);
- glEvalCoord2f(0.0,(v_bottom+1)*t_1);
- glEvalCoord2f(s_1,(v_bottom+1)*t_1);
- }
- glEnd();
- }
-
- void
- tesselate_top_left_corner(GLenum display_mode, GLint u_right, GLint u_left,
- GLfloat s_1, GLfloat t_1)
- {
- if(display_mode==GL_FILL)
- {
- glBegin(GL_TRIANGLE_FAN);
- glEvalPoint2(u_right,1);
- glEvalCoord2f((u_left+1)*s_1,t_1);
- glEvalCoord2f((u_left+1)*s_1,0.0);
- glEvalCoord2f(u_left*s_1,0.0);
- }
- else
- {
- glBegin(GL_LINES);
- glEvalCoord2f((u_left+1)*s_1,0.0);
- glEvalPoint2(u_right,1);
- glEvalCoord2f((u_left+1)*s_1,0.0);
- glEvalCoord2f(u_left*s_1,0.0);
- glEvalCoord2f((u_left+1)*s_1,0.0);
- glEvalCoord2f((u_left+1)*s_1,t_1);
- }
- glEnd();
- }
-
- void
- tesselate_top_right_corner(GLenum display_mode, GLint u_left, GLint v_bottom,
- GLint u_right, GLint v_top, GLfloat s_1, GLfloat t_1)
- {
- if(display_mode==GL_FILL)
- {
- glBegin(GL_TRIANGLE_FAN);
- glEvalPoint2(u_left,v_bottom);
- glEvalCoord2f((u_right-1)*s_1,v_top*t_1);
- glEvalCoord2f(u_right*s_1,v_top*t_1);
- glEvalCoord2f(u_right*s_1,(v_top-1)*t_1);
- }
- else
- {
- glBegin(GL_LINES);
- glEvalCoord2f(u_right*s_1,v_top*t_1);
- glEvalPoint2(u_left,v_bottom);
- glEvalCoord2f(u_right*s_1,v_top*t_1);
- glEvalCoord2f(u_right*s_1,(v_top-1)*t_1);
- glEvalCoord2f(u_right*s_1,v_top*t_1);
- glEvalCoord2f((u_right-1)*s_1,v_top*t_1);
- }
- glEnd();
- }
-
- /* do mesh mapping of Bezier */
- static void
- nurbs_map_bezier(GLenum display_mode,GLint *sfactors,GLint *tfactors,
- GLint s_bezier_cnt, GLint t_bezier_cnt, GLint s, GLint t)
- {
- GLint top,bottom,right,left;
-
-
- if(s==0)
- {
- top=*(tfactors+t*3);
- bottom=*(tfactors+t*3+1);
- }
- else
- if(s==s_bezier_cnt-1)
- {
- top=*(tfactors+t*3+2);
- bottom=*(tfactors+t*3);
- }
- else
- {
- top=bottom=*(tfactors+t*3);
- }
- if(t==0)
- {
- left=*(sfactors+s*3+1);
- right=*(sfactors+s*3);
- }
- else
- if(t==t_bezier_cnt-1)
- {
- left=*(sfactors+s*3);
- right=*(sfactors+s*3+2);
- }
- else
- {
- left=right=*(sfactors+s*3);
- }
-
- if(top>bottom)
- {
- if(left<right)
- {
- glMapGrid2f(right, 0.0, 1.0, top, 0.0, 1.0);
- glEvalMesh2(display_mode,1,right, 1, top);
- tesselate_strip_s(display_mode,1,right,1,1,left,0,(GLfloat)left);
- tesselate_bottom_left_corner(display_mode,(GLfloat)(1.0/left),
- (GLfloat)(1.0/bottom));
- /* tesselate_strip_t(display_mode,1,top,1,1,bottom,0,(GLfloat)bottom);*/
- tesselate_strip_t(display_mode,top,1,1,bottom,1,0,(GLfloat)bottom);
- }
- else
- if(left==right)
- {
- glMapGrid2f(right, 0.0, 1.0, top, 0.0, 1.0);
- glEvalMesh2(display_mode,1,right, 0, top);
- /* tesselate_strip_t(display_mode,0,top,1,0,bottom,0,(GLfloat)bottom);*/
- tesselate_strip_t(display_mode,top,0,1,bottom,0,0,(GLfloat)bottom);
- }
- else
- {
- glMapGrid2f(left, 0.0, 1.0, top, 0.0, 1.0);
- glEvalMesh2(display_mode,1,left, 0, top-1);
- /* tesselate_strip_t(display_mode,0,top-1,1,0,bottom-1,0,
- (GLfloat)bottom);*/
- tesselate_strip_t(display_mode,top-1,0,1,bottom-1,0,0,
- (GLfloat)bottom);
- tesselate_bottom_right_corner(display_mode,top-1,bottom-1,
- (GLfloat)(1.0/right),(GLfloat)(1.0/bottom));
- /* tesselate_strip_s(display_mode,1,left,top-1,1,right,right,
- (GLfloat)right);*/
- tesselate_strip_s(display_mode,left,1,top-1,right,1,right,
- (GLfloat)right);
- }
- }
- else
- if(top==bottom)
- {
- if(left<right)
- {
- glMapGrid2f(right, 0.0, 1.0, top, 0.0, 1.0);
- glEvalMesh2(display_mode,0,right, 1, top);
- tesselate_strip_s(display_mode,0,right,1,0,left,0,(GLfloat)left);
- }
- else
- if(left==right)
- {
- glMapGrid2f(right, 0.0, 1.0, top, 0.0, 1.0);
- glEvalMesh2(display_mode,0,right, 0, top);
- }
- else
- {
- glMapGrid2f(left, 0.0, 1.0, top, 0.0, 1.0);
- glEvalMesh2(display_mode,0,left, 0, top-1);
- /* tesselate_strip_s(display_mode,0,left,top-1,0,right,right,
- (GLfloat)right);*/
- tesselate_strip_s(display_mode,left,0,top-1,right,0,right,
- (GLfloat)right);
- }
- }
- else
- {
- if(left<right)
- {
- glMapGrid2f(right, 0.0, 1.0, bottom, 0.0, 1.0);
- glEvalMesh2(display_mode,0,right-1, 1, bottom);
- tesselate_strip_s(display_mode,0,right-1,1,0,left-1,0,
- (GLfloat)left);
- tesselate_top_left_corner(display_mode,right-1,left-1,
- (GLfloat)(1.0/left),(GLfloat)(1.0/top));
- tesselate_strip_t(display_mode,1,bottom,right-1,1,top,top,
- (GLfloat)top);
- }
- else
- if(left==right)
- {
- glMapGrid2f(right, 0.0, 1.0, bottom, 0.0, 1.0);
- glEvalMesh2(display_mode,0,right-1, 0, bottom);
- tesselate_strip_t(display_mode,0,bottom,right-1,0,top,top,
- (GLfloat)top);
- }
- else
- {
- glMapGrid2f(left, 0.0, 1.0, bottom, 0.0, 1.0);
- glEvalMesh2(display_mode,0,left-1, 0, bottom-1);
- tesselate_strip_t(display_mode,0,bottom-1,left-1,0,top-1,top,
- (GLfloat)top);
- tesselate_top_right_corner(display_mode,left-1,bottom-1,right,top,
- (GLfloat)(1.0/right),(GLfloat)(1.0/top));
- /* tesselate_strip_s(display_mode,0,left-1,bottom-1,0,right-1,right,
- (GLfloat)right);*/
- tesselate_strip_s(display_mode,left-1,0,bottom-1,right-1,0,right,
- (GLfloat)right);
- }
- }
- }
-
- /* draw NURBS surface in OUTLINE POLYGON mode */
- static void
- draw_polygon_mode( GLenum display_mode, GLUnurbsObj *nobj,
- new_ctrl_type *new_ctrl, GLint *sfactors, GLint *tfactors )
- {
- GLsizei offset;
- GLint t_bezier_cnt,s_bezier_cnt;
- GLboolean do_color,do_normal,do_texture;
- GLint i,j;
-
- t_bezier_cnt=new_ctrl->t_bezier_cnt;
- s_bezier_cnt=new_ctrl->s_bezier_cnt;
- glEnable(nobj->surface.geom.type);
- if(new_ctrl->color_ctrl)
- {
- glEnable(nobj->surface.color.type);
- do_color=GL_TRUE;
- }
- else
- do_color=GL_FALSE;
- if(new_ctrl->normal_ctrl)
- {
- glEnable(nobj->surface.normal.type);
- do_normal=GL_TRUE;
- }
- else
- do_normal=GL_FALSE;
- if(new_ctrl->texture_ctrl)
- {
- glEnable(nobj->surface.texture.type);
- do_texture=GL_TRUE;
- }
- else
- do_texture=GL_FALSE;
- for(j=0; j<s_bezier_cnt; j++)
- {
- for(i=0; i<t_bezier_cnt; i++)
- {
- offset=j*t_bezier_cnt + i;
- if(fine_culling_test_3D(nobj,*(new_ctrl->geom_offsets + offset),
- nobj->surface.geom.sorder,nobj->surface.geom.torder,
- new_ctrl->geom_s_stride,new_ctrl->geom_t_stride,
- nobj->surface.geom.dim))
- continue;
- glMap2f(nobj->surface.geom.type,0.0,1.0,new_ctrl->geom_s_stride,
- nobj->surface.geom.sorder,0.0,1.0,new_ctrl->geom_t_stride,
- nobj->surface.geom.torder,*(new_ctrl->geom_offsets + offset));
- if(do_color)
- {
- glMap2f(nobj->surface.color.type,0.0,1.0,
- new_ctrl->color_s_stride,nobj->surface.color.sorder,
- 0.0,1.0,new_ctrl->color_t_stride,nobj->surface.color.torder,
- *(new_ctrl->color_offsets + offset));
- }
- if(do_normal)
- {
- glMap2f(nobj->surface.normal.type,0.0,1.0,
- new_ctrl->normal_s_stride,nobj->surface.normal.sorder,
- 0.0,1.0,new_ctrl->normal_t_stride,
- nobj->surface.normal.torder,
- *(new_ctrl->normal_offsets+offset));
- }
- if(do_texture)
- {
- glMap2f(nobj->surface.texture.type,0.0,1.0,
- new_ctrl->texture_s_stride,nobj->surface.texture.sorder,
- 0.0,1.0,new_ctrl->texture_t_stride,
- nobj->surface.texture.torder,
- *(new_ctrl->texture_offsets+offset));
- }
- /* glMapGrid2f(sfactors[j*3+0],0.0,1.0,tfactors[i*3+0],0.0,1.0);
- glEvalMesh2(display_mode,0,sfactors[j*3+0],0,tfactors[i*3+0]);*/
- nurbs_map_bezier(display_mode,sfactors,tfactors,s_bezier_cnt,
- t_bezier_cnt,j,i);
- }
- }
- }
-
-
-
- /* draw NURBS surface in OUTLINE POLYGON mode */
- #if 0
- static void
- draw_patch_mode( GLenum display_mode, GLUnurbsObj *nobj,
- new_ctrl_type *new_ctrl, GLint *sfactors, GLint *tfactors )
- {
- GLsizei offset;
- GLint t_bezier_cnt,s_bezier_cnt;
- GLboolean do_color,do_normal,do_texture;
- GLint i,j;
-
- t_bezier_cnt=new_ctrl->t_bezier_cnt;
- s_bezier_cnt=new_ctrl->s_bezier_cnt;
- glEnable(nobj->surface.geom.type);
- if(new_ctrl->color_ctrl)
- {
- glEnable(nobj->surface.color.type);
- do_color=GL_TRUE;
- }
- else
- do_color=GL_FALSE;
- if(new_ctrl->normal_ctrl)
- {
- glEnable(nobj->surface.normal.type);
- do_normal=GL_TRUE;
- }
- else
- do_normal=GL_FALSE;
- if(new_ctrl->texture_ctrl)
- {
- glEnable(nobj->surface.texture.type);
- do_texture=GL_TRUE;
- }
- else
- do_texture=GL_FALSE;
- for(j=0; j<s_bezier_cnt; j++)
- {
- for(i=0; i<t_bezier_cnt; i++)
- {
- offset=j*t_bezier_cnt + i;
- if(fine_culling_test_3D(nobj,*(new_ctrl->geom_offsets + offset),
- nobj->surface.geom.sorder,nobj->surface.geom.torder,
- new_ctrl->geom_s_stride,new_ctrl->geom_t_stride,
- nobj->surface.geom.dim))
- continue;
- glMap2f(nobj->surface.geom.type,0.0,1.0,new_ctrl->geom_s_stride,
- nobj->surface.geom.sorder,0.0,1.0,new_ctrl->geom_t_stride,
- nobj->surface.geom.torder,*(new_ctrl->geom_offsets + offset));
- if(do_color)
- {
- glMap2f(nobj->surface.color.type,0.0,1.0,
- new_ctrl->color_s_stride,nobj->surface.color.sorder,
- 0.0,1.0,new_ctrl->color_t_stride,nobj->surface.color.torder,
- *(new_ctrl->color_offsets + offset));
- }
- if(do_normal)
- {
- glMap2f(nobj->surface.normal.type,0.0,1.0,
- new_ctrl->normal_s_stride,nobj->surface.normal.sorder,
- 0.0,1.0,new_ctrl->normal_t_stride,
- nobj->surface.normal.torder,
- *(new_ctrl->normal_offsets+offset));
- }
- if(do_texture)
- {
- glMap2f(nobj->surface.texture.type,0.0,1.0,
- new_ctrl->texture_s_stride,nobj->surface.texture.sorder,
- 0.0,1.0,new_ctrl->texture_t_stride,
- nobj->surface.texture.torder,
- *(new_ctrl->texture_offsets+offset));
- }
- nurbs_map_bezier(display_mode,sfactors,tfactors,s_bezier_cnt,
- t_bezier_cnt,i,j);
- /* glMapGrid2f(sfactors[j],0.0,1.0,tfactors[i],0.0,1.0);
- glEvalMesh2(display_mode,0,sfactors[j],0,tfactors[i]);*/
- }
- }
- }
- #endif
-
-
-
- void
- init_new_ctrl(new_ctrl_type *p)
- {
- p->geom_ctrl=p->color_ctrl=p->normal_ctrl=p->texture_ctrl=NULL;
- p->geom_offsets=p->color_offsets=p->normal_offsets=p->texture_offsets=NULL;
- p->s_bezier_cnt=p->t_bezier_cnt=0;
- }
-
- GLenum
- augment_new_ctrl(GLUnurbsObj *nobj, new_ctrl_type *p)
- {
- GLsizei offset_size;
- GLint i,j;
-
- p->s_bezier_cnt=(p->geom_s_pt_cnt)/(nobj->surface.geom.sorder);
- p->t_bezier_cnt=(p->geom_t_pt_cnt)/(nobj->surface.geom.torder);
- offset_size=(p->s_bezier_cnt)*(p->t_bezier_cnt);
- p->geom_t_stride=nobj->surface.geom.dim;
- p->geom_s_stride=(p->geom_t_pt_cnt)*(nobj->surface.geom.dim);
- p->color_t_stride=nobj->surface.color.dim;
- p->color_s_stride=(p->color_t_pt_cnt)*(nobj->surface.color.dim);
- p->normal_t_stride=nobj->surface.normal.dim;
- p->normal_s_stride=(p->normal_t_pt_cnt)*(nobj->surface.normal.dim);
- p->texture_t_stride=nobj->surface.texture.dim;
- p->texture_s_stride=(p->texture_t_pt_cnt)*(nobj->surface.texture.dim);
- if((p->geom_offsets=(GLfloat **)malloc(sizeof(GLfloat *)*offset_size))==NULL)
- {
- call_user_error(nobj,GLU_OUT_OF_MEMORY);
- return GLU_ERROR;
- }
- if(p->color_ctrl)
- if((p->color_offsets=(GLfloat **)malloc(sizeof(GLfloat *)*offset_size))==NULL)
- {
- free_new_ctrl(p);
- call_user_error(nobj,GLU_OUT_OF_MEMORY);
- return GLU_ERROR;
- }
- if(p->normal_ctrl)
- if((p->normal_offsets=(GLfloat **)malloc(sizeof(GLfloat *)*offset_size))==NULL)
- {
- free_new_ctrl(p);
- call_user_error(nobj,GLU_OUT_OF_MEMORY);
- return GLU_ERROR;
- }
- if(p->texture_ctrl)
- if((p->texture_offsets=(GLfloat **)malloc(sizeof(GLfloat *)*offset_size))==NULL)
- {
- free_new_ctrl(p);
- call_user_error(nobj,GLU_OUT_OF_MEMORY);
- return GLU_ERROR;
- }
- for(i=0;i<p->s_bezier_cnt;i++)
- for(j=0;j<p->t_bezier_cnt;j++)
- *(p->geom_offsets + i*(p->t_bezier_cnt) + j) =
- p->geom_ctrl + i*(nobj->surface.geom.sorder)*
- (nobj->surface.geom.dim)*(p->geom_t_pt_cnt) +
- j*(nobj->surface.geom.dim)*(nobj->surface.geom.torder);
- if(p->color_ctrl)
- for(i=0;i<p->s_bezier_cnt;i++)
- for(j=0;j<p->t_bezier_cnt;j++)
- *(p->color_offsets + i*(p->t_bezier_cnt) + j) =
- p->color_ctrl + i*(nobj->surface.color.sorder)*
- (nobj->surface.color.dim)*(p->color_t_pt_cnt) +
- j*(nobj->surface.color.dim)*(nobj->surface.color.torder);
- if(p->normal_ctrl)
- for(i=0;i<p->s_bezier_cnt;i++)
- for(j=0;j<p->t_bezier_cnt;j++)
- *(p->normal_offsets + i*(p->t_bezier_cnt) + j) =
- p->normal_ctrl + i*(nobj->surface.normal.sorder)*
- (nobj->surface.normal.dim)*(p->normal_t_pt_cnt) +
- j*(nobj->surface.normal.dim)*(nobj->surface.normal.torder);
- if(p->texture_ctrl)
- for(i=0;i<p->s_bezier_cnt;i++)
- for(j=0;j<p->t_bezier_cnt;j++)
- *(p->texture_offsets + i*(p->t_bezier_cnt) + j) =
- p->texture_ctrl + i*(nobj->surface.texture.sorder)*
- (nobj->surface.texture.dim)*(p->texture_t_pt_cnt) +
- j*(nobj->surface.texture.dim)*(nobj->surface.texture.torder);
- return GLU_NO_ERROR;
- }
-
- /* main NURBS surface procedure */
- void
- do_nurbs_surface( GLUnurbsObj *nobj )
- {
- GLint *sfactors,*tfactors;
- new_ctrl_type new_ctrl;
-
- /* test user supplied data */
- if(test_nurbs_surfaces(nobj)!=GLU_NO_ERROR)
- return;
-
- init_new_ctrl(&new_ctrl);
-
- if(convert_surfs(nobj,&new_ctrl)!=GLU_NO_ERROR)
- return;
- if(augment_new_ctrl(nobj,&new_ctrl)!=GLU_NO_ERROR)
- return;
- if(glu_do_sampling_3D(nobj,&new_ctrl,&sfactors,&tfactors)!=GLU_NO_ERROR)
- {
- free_new_ctrl(&new_ctrl);
- return;
- }
- switch(nobj->display_mode)
- {
- case GLU_FILL:
- /* if(polygon_trimming(nobj,&new_ctrl,sfactors,tfactors)==GLU_NO_ERROR)*/
- draw_polygon_mode(GL_FILL,nobj,&new_ctrl,sfactors,tfactors);
- break;
- case GLU_OUTLINE_POLYGON:
- /* TODO - missing trimming handeling */
- /* just for now - no OUTLINE_PATCH mode
- draw_patch_mode(GL_LINE,nobj,&new_ctrl,sfactors,tfactors);
- break; */
- case GLU_OUTLINE_PATCH:
- /* if(polygon_trimming(nobj,&new_ctrl,sfactors,tfactors)==GLU_NO_ERROR)*/
- draw_polygon_mode(GL_LINE,nobj,&new_ctrl,sfactors,tfactors);
- break;
- default:
- abort(); /* TODO: is this OK? */
- }
- free(sfactors);
- free(tfactors);
- free_new_ctrl(&new_ctrl);
- }
-
-